from cat_rfs.code.simulate.simulate import simulate

PERILS = ['Asia Earthquake', 'Asia Cyclone',
          'Europe Earthquake', 'Europe Cyclone',
          'North_america Earthquake', 'North_america Cyclone',
          'Middle_america Earthquake', 'Middle_america Cyclone',
          'South_america Earthquake']


def estimate_betas(df):
    """Estimate simulated betas using several different methodologies and save to csv."""
    dfe = df[['CUSIP9', 'date']].copy()

    # %% Create betas for each of the following combinations
    # 1. sheet yield, trace yield, discount margin = 0
    # 2. equally and value weighted
    # 3. normal and wsst actuarial probabilities
    # y = 'sheet_yield_usd', ew=False, wsst=False creates the "main" beta estimates used in the paper.
    for y in ['sheet_yield_usd', 'act_yield_usd', 'loss']:
        for ew in [False, True]:
            if ew == True and y == 'loss':
                continue
            for wsst in [False, True]:
                if wsst == True and y == 'loss':
                    continue
                df2 = df.copy()
                name = ''
                if y == 'sheet_yield_usd':
                    name += '_sheet'
                    var = 'return'
                    df2 = df2.rename(columns={'sheet_yield_usd': 'yield'})
                    df2 = df2.dropna(subset=['yield'])
                elif y == 'act_yield_usd':
                    name += '_act'
                    var = 'return'
                    df2 = df2.rename(columns={'act_yield_usd': 'yield'})
                    df2 = df2[(df2['date'] >= '12/31/2004') & (df2['date'] <= '12/31/2018')]
                    df2 = df2.dropna(subset=['yield'])
                elif y == 'loss':
                    name += '_loss'
                    var = 'loss'

                if ew:
                    name += '_ew'

                if wsst is True:
                    name += '_wsst'
                    for v in ['attachment_prob', 'expected_loss', 'exhaustion_prob']:
                        df2 = df2.drop(columns=v)
                        df2 = df2.rename(columns={v+'_wsst': v})
                    for p in PERILS:
                        for v in ('ap', 'el', 'ep'):
                            vname = f"{v}_{p.replace(' ', '_').lower()}"
                            df2 = df2.drop(columns=vname)
                            df2 = df2.rename(columns={vname + '_wsst': vname})

                df2 = simulate(df2, 500000, var=var, lambda_='actual', ew=ew, randomize_perils=False,
                               date_list=list(df2['date'].unique()))[['CUSIP9', 'date', 'beta', 'var', 'var_m']]
                df2 = df2.rename(columns={'beta': 'beta' + name, 'var': 'var' + name, 'var_m': 'var_m' + name})

                dfe = dfe.merge(df2, on=['CUSIP9', 'date'], how='outer', validate='1:1')

    # %% Randomize perils
    df2 = df.copy()
    df2 = df2.rename(columns={'sheet_yield_usd': 'yield'})
    df2 = df2.dropna(subset=['yield'])
    df2 = simulate(df2, 500000, var='return', lambda_='actual', ew=False, randomize_perils=True,
                   date_list=list(df['date'].unique()))[['CUSIP9', 'date', 'beta', 'var', 'var_m']]

    df2 = df2.rename(columns={'beta': 'beta_random_peril', 'var': 'var_random_peril', 'var_m': 'var_m_random_peril'})

    dfe = dfe.merge(df2, on=['CUSIP9', 'date'], how='outer', validate='1:1')

    # %% Equalize expected loss to 2%
    df2 = df.copy()
    df2 = df2.rename(columns={'sheet_yield_usd': 'yield'})
    df2 = df2.dropna(subset=['yield'])
    df2 = simulate(df2, 500000, var='return', lambda_='actual', ew=False, randomize_perils=False, equalize_el=2,
                   date_list=list(df['date'].unique()))[['CUSIP9', 'date', 'beta', 'var', 'var_m']]

    df2 = df2.rename(columns={'beta': 'beta_equal_el', 'var': 'var_equal_el', 'var_m': 'var_m_equal_el'})

    dfe = dfe.merge(df2, on=['CUSIP9', 'date'], how='outer', validate='1:1')

    # %% Full placebo
    df2 = df.copy()
    df2 = df2.rename(columns={'sheet_yield_usd': 'yield'})
    df2 = df2.dropna(subset=['yield'])
    df2 = simulate(df2, 500000, var='loss', lambda_='actual', ew=True, randomize_perils=True, equalize_el=2,
                   date_list=list(df['date'].unique()))[['CUSIP9', 'date', 'beta', 'var', 'var_m']]

    df2 = df2.rename(columns={'beta': 'beta_equalize_all', 'var': 'var_equalize_all', 'var_m': 'var_m_equalize_all'})

    dfe = dfe.merge(df2, on=['CUSIP9', 'date'], how='outer', validate='1:1')

    # %% Within-category correlation = 0.75
    df2 = df.copy()
    df2 = df2.rename(columns={'sheet_yield_usd': 'yield'})
    df2 = df2.dropna(subset=['yield'])
    df2 = simulate(df2, 500000, var='return', lambda_='actual', ew=False, randomize_perils=False, issue_level_corr=0.75,
                   date_list=list(df['date'].unique()))[['CUSIP9', 'date', 'beta', 'var', 'var_m']]

    df2 = df2.rename(columns={'beta': 'beta_corr75', 'var': 'var_corr75', 'var_m': 'var_m_corr75'})

    dfe = dfe.merge(df2, on=['CUSIP9', 'date'], how='outer', validate='1:1')

    # %% Within-category correlation = 0.5
    df2 = df.copy()
    df2 = df2.rename(columns={'sheet_yield_usd': 'yield'})
    df2 = df2.dropna(subset=['yield'])
    df2 = simulate(df2, 500000, var='return', lambda_='actual', ew=False, randomize_perils=False, issue_level_corr=0.5,
                   date_list=list(df['date'].unique()))[['CUSIP9', 'date', 'beta', 'var', 'var_m']]

    df2 = df2.rename(columns={'beta': 'beta_corr50', 'var': 'var_corr50', 'var_m': 'var_m_corr50'})

    dfe = dfe.merge(df2, on=['CUSIP9', 'date'], how='outer', validate='1:1')

    # %% Within-category correlation = 0.25
    df2 = df.copy()
    df2 = df2.rename(columns={'sheet_yield_usd': 'yield'})
    df2 = df2.dropna(subset=['yield'])
    df2 = simulate(df2, 500000, var='return', lambda_='actual', ew=False, randomize_perils=False, issue_level_corr=0.25,
                   date_list=list(df['date'].unique()))[['CUSIP9', 'date', 'beta', 'var', 'var_m']]

    df2 = df2.rename(columns={'beta': 'beta_corr25', 'var': 'var_corr25', 'var_m': 'var_m_corr25'})

    dfe = dfe.merge(df2, on=['CUSIP9', 'date'], how='outer', validate='1:1')

    # %% Save output
    dfe.to_csv('cat_rfs/data/betas_reconstructed.csv', index=False)

    pass
